package com.java.member.service.impl;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.BCrypt;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.java.common.vo.R;
import com.java.member.compoent.AsyncTask;
import com.java.member.entity.MyUser;
import com.java.member.mapper.MyUserMapper;
import com.java.member.service.MyUserService;
import com.java.member.vo.UserVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author jiangli
 * @since 2019-12-09
 */
@Service
public class MyUserServiceImpl extends ServiceImpl<MyUserMapper, MyUser> implements MyUserService {
	@Autowired
	private AsyncTask asyncTask;
	@Autowired
	private StringRedisTemplate redisTemplate;

	public static final String LOGIN_KEY = "login_key";

	@Override
	@Transactional
	public R registry(MyUser myUser) {
		String hashed = BCrypt.hashpw(myUser.getPassword(), BCrypt.gensalt());
		myUser.setPassword(hashed);
		this.baseMapper.insert(myUser);
		//异步发送邮件
		asyncTask.sendEmailHtml(myUser.getEmail(), "注册成功", myUser.getUsername());
		return R.ok();
	}

	@Override
	public R login(String username, String password) {
		//通过用户名查询数据库
		MyUser dbUser = this.baseMapper.selectOne(new LambdaQueryWrapper<MyUser>().eq(MyUser::getUsername, username));
		if (dbUser == null) {
			return R.error("用户不存在");
		}
		//比较用户输入的密码和数据库的密码
		boolean checkpw = BCrypt.checkpw(password, dbUser.getPassword());
		if (!checkpw) {
			return R.error("用户名或密码错误");
		}
		//生成token
		String token = fetchToken(dbUser);
		return R.ok(token);
	}

	@Override
	public R getUserInfo(String token) {
		String userId = redisTemplate.opsForValue().get(LOGIN_KEY + token);
		if (StrUtil.isEmpty(userId)) {
			return R.error("请重新登录");
		}
		MyUser myUser = this.baseMapper.selectById(userId);
		//过滤敏感字段
		UserVO userVO = new UserVO();
		BeanUtils.copyProperties(myUser, userVO);
		return R.ok(userVO);
	}

	@Override
	public R loginByOpenid(String openid, String nickname) {
		MyUser myUser = this.baseMapper.selectOne(new LambdaQueryWrapper<MyUser>().eq(MyUser::getOpenid, openid));
		if (myUser == null) {
			//自动注册用户
			myUser = new MyUser().setUsername(nickname).setOpenid(openid);
			this.baseMapper.insert(myUser);
		}
		//已关联,生成用户登录凭证token并返回
		String token = fetchToken(myUser);
		return R.ok(token);
	}

	private String fetchToken(MyUser myUser) {
		String token = RandomUtil.randomString(32);
		//保存到redis key=token value=userId
		redisTemplate.opsForValue().set(LOGIN_KEY + token, myUser.getId(), 2, TimeUnit.HOURS);
		return token;
	}

}
